import 'dart:io';
import 'dart:math';

import 'package:alive_flutter_plugin/alive_flutter_plugin.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:xindong/common/xindong_sezhi.dart';
import 'package:xindong/common/xindong_define.dart';
import 'package:xindong/extension/extension_string.dart';
import 'package:xindong/manager/xindong_page_singleton.dart';
import 'package:xindong/res/assets_res.dart';
import 'package:xindong/widgets/common/xindong_app_bar.dart';
import 'package:xindong/widgets/common/xindong_app_bar_icon_button.dart';
import 'package:xindong/widgets/dialog/xindong_alert_options.dart';
import 'package:xindong/widgets/dialog/xindong_base_sheet.dart';
import 'package:xindong/widgets/xindong_common_yemian_indicator.dart';
import 'package:xindong/widgets/xindong_gradient_circular_progress_indicator.dart';
import 'package:xindong/widgets/xindong_loading.dart';

// 活体检测
class XinDongAuthLiveDetectYeMian extends StatefulWidget {
  final bool isLoginStatus; // 是不是登录状态
  final Function(String token) doneCallback; // 认证完成回调

  const XinDongAuthLiveDetectYeMian({Key? key, required this.isLoginStatus, required this.doneCallback})
      : super(key: key);

  XinDongAuthLiveDetectYeMian.show({super.key, required this.isLoginStatus, required this.doneCallback}) {
    XinDongPageSingleton.instance.pushYeMian(this);
  }

  static hide() {
    Get.back();
  }

  @override
  State<XinDongAuthLiveDetectYeMian> createState() => _XinDongAuthLiveDetectYeMianState();
}

class _XinDongAuthLiveDetectYeMianState extends State<XinDongAuthLiveDetectYeMian> {
  final AliveFlutterPlugin aliveFlutterPlugin = AliveFlutterPlugin();
  final eventChannel = const EventChannel("yd_alive_flutter_event_channel");
  final int timeout = 20; // 超时时间（秒）
  final AudioPlayer audioPlayer = AudioPlayer();
  late String _audioFilePath = "";

  bool isLoading = true;
  late List actionList = []; // 动作列表
  late int startMilliseconds = 0; // 开始到时间戳
  late double progressTimeout = 0.0; // 超时进度
  String _resultTips = ""; // 结果提示
  String _actionTips = "请将脸部展示在画面中"; // 动作提示
  int _currentStep = 0; // 当前动作步骤

  // 开始
  void startLive() {
    progressTimeout = 0.0;
    aliveFlutterPlugin.startLiveDetect().then((value) {
      /**
       * action表示返回的动作，动作状态表示：0——正面，1——右转，2——左转，3——张嘴，4——眨眼。
       */
      String actions = value["data"]["actions"];
      setState(() {
        startMilliseconds = DateTime.now().millisecondsSinceEpoch;
        isLoading = false;
        actionList = actions.stringToList(pattern: "");
        actionList.remove("0");
      });
    });
  }

  // 结束
  void stopLive() {
    progressTimeout = 1.0;
    _currentStep = 0;
    aliveFlutterPlugin.stopLiveDetect();
  }

  @override
  void initState() {
    super.initState();
    audioPlayer.setLoopMode(LoopMode.off);
    audioPlayer.setVolume(1.0);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      aliveFlutterPlugin.init(kBusinessID, timeout);
      startLive();
    });
    eventChannel.receiveBroadcastStream().listen(_onData, onError: _onError);
  }

  @override
  void dispose() {
    audioPlayer.stop();
    aliveFlutterPlugin.stopLiveDetect();
    // Android需要释放资源，否则会引发内存泄露
    if (defaultTargetPlatform == TargetPlatform.android) {
      aliveFlutterPlugin.destroy();
    }
    super.dispose();
  }

  void _onData(response) {
    if (response is Map) {
      setState(() {
        progressTimeout = (DateTime.now().millisecondsSinceEpoch - startMilliseconds) / (timeout * 1000);
        var type = response["method"];
        var data = response["data"];
        // 检查动作 0：正视前方 1：向右转头 2：向左转头 3：张嘴动作 4：眨眼动作
        if (type == "onChecking") {
          _currentStep = data["currentStep"];
          if (_currentStep != 6) {
            // 动作成功
            _actionTips = data["message"];
          }
        }

        // 检测完成
        else if (type == "onChecked" || type == "checked") {
          stopLive();
          _currentStep = 0;
          bool isPassed = data["isPassed"];
          String token = data["token"];
          if (isPassed) {
            widget.doneCallback(token);
            XinDongAuthLiveDetectYeMian.hide();
          } else {
            XinDongAlertOptions.show(
              content: '认证失败',
              leftName: "重试",
              rightName: "退出认证",
              onTapLeft: () {
                startLive();
              },
              onTapRight: () {
                XinDongAuthLiveDetectYeMian.hide();
              },
            );
          }
        }

        // 异常状态 1：保持面部在框内 2：环境光线过暗 3：环境光线过亮 4：请勿抖动手机
        else if (type == "onError") {
          if (data["message"] == null) {
            _resultTips = "认证中断，请切换网络再试";
          } else {
            _resultTips = data["message"];
          }
          if (Platform.isAndroid && _resultTips == "timeout") {
            stopLive();
            XinDongAlertOptions.show(
              content: '检测超时',
              leftName: "重试",
              rightName: "退出认证",
              onTapLeft: () {
                startLive();
              },
              onTapRight: () {
                XinDongAuthLiveDetectYeMian.hide();
              },
            );
          }
        } else if (type == "overTime") {
          stopLive();
          XinDongAlertOptions.show(
            content: '检测超时',
            leftName: "重试",
            rightName: "退出认证",
            onTapLeft: () {
              startLive();
            },
            onTapRight: () {
              XinDongAuthLiveDetectYeMian.hide();
            },
          );
        }
      });
    }
  }

  _onError(Object error) {
    PlatformException exception = error as PlatformException;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: XinDongAppBar(widget.isLoginStatus ? "本人登录检测" : "活体检测", elevation: 0),
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          ListView(
            children: [
              const SizedBox(height: 20),
              _buildFaceWidget(),
              // showDetailText(),
            ],
          ),
          isLoading
              ? const XinDongLoadingCenter()
              : Column(
                  children: [
                    const Expanded(child: SizedBox()),
                    showAnimatedGif(),

                    // 索引
                    SizedBox(
                      height: 30,
                      child: XinDongCommonYeMianIndicator(
                        currentIndex: actionList.indexOf(_currentStep.toString()),
                        totalCount: actionList.length,
                      ),
                    ),
                    SizedBox(height: 26 + bottomBarHeight),
                  ],
                )
        ],
      ),
    );
  }

  Widget _buildFaceWidget() {
    final faceSize = screenWidth - 46 * 2;
    return Center(
      child: Stack(
        fit: StackFit.loose,
        clipBehavior: Clip.none,
        alignment: Alignment.center,
        children: [
          Container(
            width: faceSize,
            height: faceSize,
            clipBehavior: Clip.antiAlias,
            decoration: BoxDecoration(borderRadius: BorderRadius.circular(faceSize)),
            child: Stack(
              children: [
                defaultTargetPlatform == TargetPlatform.android
                    ? Center(
                        child: Container(
                          width: faceSize,
                          height: faceSize * 4 / 3,
                          alignment: Alignment.center,
                          child: AndroidView(
                            viewType: 'platform-view-alive',
                            creationParams: {"width": faceSize.toInt(), "height": (faceSize * 4 ~/ 3).toInt()},
                            creationParamsCodec: const StandardMessageCodec(),
                          ),
                        ),
                      )
                    : defaultTargetPlatform == TargetPlatform.iOS
                        ? SizedBox(
                            width: faceSize,
                            height: faceSize,
                            child: UiKitView(
                              viewType: 'com.flutter.alive.imageview',
                              creationParams: {
                                "width": "$faceSize",
                                "height": "$faceSize",
                                "radius": "${faceSize / 2}",
                              },
                              //参数的编码方式
                              creationParamsCodec: const StandardMessageCodec(),
                            ),
                          )
                        : Text('$defaultTargetPlatform is not yet supported by this plugin'),
                _buildActionText(faceSize),
              ],
            ),
          ),
          // 进度条
          Transform.rotate(
            angle: -pi + pi / 5,
            child: XinDongGradientCircularProgressIndicator(
              value: progressTimeout,
              radius: faceSize / 2 + 16,
              strokeWidth: 2.0,
              strokeCapRound: true,
              totalAngle: 2 * pi - pi / 2.5,
              backgroundColor: DZColors.backgroundColor,
              colors: const [DZColors.mainLightColor, DZColors.mainColor],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildActionText(double width) {
    return Container(
      height: 40,
      alignment: Alignment.center,
      color: Colors.black12,
      padding: EdgeInsets.only(left: width / 4, right: width / 4, top: 5),
      child: Text(
        _actionTips,
        textAlign: TextAlign.center,
        style: const TextStyle(fontSize: 10, color: Colors.white),
      ),
    );
  }

  Widget showAnimatedGif() {
    /**
     * _currentStep == 1 右转
     * _currentStep == 2 左转
     * _currentStep == 3 张嘴
     * _currentStep == 4 眨眼
     */
    var image = '';
    switch (_currentStep) {
      case 1:
        {
          image = AssetsRes.FACE_TURN_RIGHT;
          const path = AssetsRes.AUDIO_TURN_RIGHT;
          if (path != _audioFilePath) {
            _audioFilePath = path;
            audioPlayer.setAsset(_audioFilePath);
            audioPlayer.play();
          }
        }
        break;
      case 2:
        {
          image = AssetsRes.FACE_TURN_LEFT;
          const path = AssetsRes.AUDIO_TURN_LEFT;
          if (path != _audioFilePath) {
            _audioFilePath = path;
            audioPlayer.setAsset(_audioFilePath);
            audioPlayer.play();
          }
        }
        break;
      case 3:
        {
          image = AssetsRes.FACE_OPEN_MOUTH;
          const path = AssetsRes.AUDIO_OPEN_MOUTH;
          if (path != _audioFilePath) {
            _audioFilePath = path;
            audioPlayer.setAsset(_audioFilePath);
            audioPlayer.play();
          }
        }
        break;
      case 4:
        {
          image = AssetsRes.FACE_OPEN_EYES;
          const path = AssetsRes.AUDIO_OPEN_EYES;
          if (path != _audioFilePath) {
            _audioFilePath = path;
            audioPlayer.setAsset(_audioFilePath);
            audioPlayer.play();
          }
        }
        break;
      default:
        image = AssetsRes.FACE_FRONT;
        break;
    }
    return SizedBox(width: 128, height: 128, child: Image.asset(image));
  }
}
